from numpy.random import RandomState
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_olivetti_faces
from sklearn import decomposition

# 设置展示排列
n_row, n_col = 2, 3
# 提取特征的数目
n_components = n_row * n_col
# 人脸数据图片的大小
image_shape = (64, 64)

###############################################################################
# Load faces data
# olivetti 400个 64*64大小 打乱顺序
dataset = fetch_olivetti_faces(shuffle=True, random_state=RandomState(0))
faces = dataset.data


###############################################################################
def plot_gallery(title, images, n_col=n_col, n_row=n_row):
    # 创建图片 指定图片大小（英寸）
    plt.figure(figsize=(2. * n_col, 2.26 * n_row))
    # 标题 字号
    plt.suptitle(title, size=16)

    for i, comp in enumerate(images):
        plt.subplot(n_row, n_col, i + 1)
        vmax = max(comp.max(), -comp.min())
        # 归一化 灰度
        plt.imshow(comp.reshape(image_shape), cmap=plt.cm.gray,
                   interpolation='nearest', vmin=-vmax, vmax=vmax)
        # 去除坐标轴标签
        plt.xticks(())
        plt.yticks(())
    # 调整位置间隔
    plt.subplots_adjust(0.01, 0.05, 0.99, 0.94, 0.04, 0.)


plot_gallery("First centered Olivetti faces", faces[:n_components])
###############################################################################

estimators = [
    # 主成分分析
    ('Eigenfaces - PCA using randomized SVD',
     decomposition.PCA(n_components=6, whiten=True)),
    # 非负矩阵分解
    # n_components 分解后矩阵的单个维度
    # init W和H矩阵的初始化方式 默认为 nndsvdar
    ('Non-negative components - NMF',
     decomposition.NMF(n_components=6, init='nndsvda', tol=5e-3))
]

###############################################################################

for name, estimator in estimators:
    print("Extracting the top %d %s..." % (n_components, name))
    print(faces.shape)
    estimator.fit(faces)
    components_ = estimator.components_
    plot_gallery(name, components_[:n_components])

plt.show()
